#!/usr/bin/env -S node -r ./livescript-transform-implicit-async/register

require! <[
  ./argv.ls
  path
  klaw
]>
require! {
  \fs-extra : fs
}


_run = (li)~>
  Promise.all [..(argv.cwd) for li]

_plugin = (plugin)~>
  r = {
    begin : []
    end : []
    file : []
    path : []
  }
  for dir, hook of plugin
    for i in <[path file]>
      d = r[i]
      for mod, re of hook[i]
        func = require(path.join(dir,mod))
        for i in d
          if i[0] == re
            i[2].push func
            break
        d.push [
          re
          new RegExp('^'+re+\$)
          [func]
        ]
    for i in <[begin end]>
      d = r[i]
      if i of hook
        for mod in hook[i]
          d.push require path.join(dir,mod)
  r


module.exports = !~>
  {cwd,config} = argv
  plugin = _plugin config.plugin

  _todo = []
  _await = (p)!~>
    if p
      _todo.push p

  await _run plugin.begin

  _todo = []

  _read = (key, func-li)!~>
    buf = buf0 = await fs.readFile key
    buf.path = key.slice(cwd.length + 1)
    for func in func-li
      f = func.file
      if not f
        continue
      r = await f buf, cwd
      if r != undefined
        if not Buffer.isBuffer(r)
          r = Buffer.from(r)
        buf = r
      if buf.compare buf0
        await fs.writeFile key, buf

  cwd-len = cwd.length + 1

  return new Promise (resolve)!~>
    klaw(
      cwd
      {
        filter:(item)!~>

          key = item.slice(cwd-len)
          if key.startsWith \.git
            return false

          for [_, r, func-li] in plugin.path
            if r.test key
              for i in func-li
                _await i.path(key)

          return true
      }
    ).on(
      \data
      (item)!~>
        if item.stats.isDirectory!
          return
        item-path = item.path
        key = item-path.slice(cwd.length+1)
        for [_, r, func-li] in plugin.file
          if r.test key
            _await _read item-path,func-li
    ).on(
      \end
      !~>
        await Promise.all _todo
        {cwd} = argv
        for name in <[path file]>
          for [_, r, func-li] in plugin[name]
            for i in func-li
              await i.end?(cwd)
        await _run plugin.end
        resolve!
    )


if require.main == module
  do !~>
    await module.exports!

